package pickers

import (
	"fmt"
	"iot-base/common/cache"
	"iot-base/common/config"
	"iot-base/common/notify"
	"iot-base/common/propertytype"
	"iot-base/common/timer"
	"runtime"
	"strconv"
	"strings"
	"sync"
	"time"

	"github.com/shirou/gopsutil/cpu"
	"github.com/shirou/gopsutil/disk"
	"github.com/shirou/gopsutil/mem"
)

//DB 数据库连接
//var DB = dbobj.DBConnection

//GetCPUPercent CPU占用率
func GetCPUPercent(isPart bool) []float64 {
	percent, err := cpu.Percent(time.Second, isPart)
	if err != nil {
		fmt.Println("get cup percent", err)
	}
	return percent
}

//GetMemPercent 内存占用率
func GetMemPercent() (float64, uint64) {
	memInfo, err := mem.VirtualMemory()
	if err != nil {
		fmt.Println("GetMemPercent ", err)
	}
	return memInfo.UsedPercent, memInfo.Total
}

//StoreInfo 存储信息
type StoreInfo struct {
	Total       float64 `json:"total" msgpack:"total"`
	UsedPercent float64 `json:"usedPercent"  msgpack:"usedPercent"`
	Mount       string  `json:"mount" msgpack:"mount"`
	Free        float64 `json:"free" msgpack:"free"`
	Used        float64 `json:"used" msgpack:"used"`
}

var diskUsed = make([]StoreInfo, 2)

//GetDiskInfo 硬盘占用率
func GetDiskInfo() ([]StoreInfo, error) {
	parts, err := disk.Partitions(true)
	if err != nil {
		return nil, err
	}
	plen := len(parts)
	dlen := len(diskUsed)
	if plen > dlen {
		for i := dlen; i < plen; i++ {
			diskUsed = append(diskUsed, StoreInfo{})
		}
	}
	diskUsed := diskUsed[:plen]
	for index, p := range parts {
		diskInfo, err := disk.Usage(p.Mountpoint)
		if err != nil {
			fmt.Println("diskinfo mount :", p.Mountpoint, " error:", err)
		}
		//diskUsed = append(diskUsed, diskInfo)
		info := &diskUsed[index]
		info.Mount = p.Mountpoint
		if diskInfo != nil {
			info.Total = float64(diskInfo.Total / (1024 * 1024 * 1024))
			info.UsedPercent = float64(diskInfo.UsedPercent)
			info.Free = float64(diskInfo.Free / (1024 * 1024 * 1024))
			info.Used = float64(diskInfo.Used / (1024 * 1024 * 1024))
		} else {
			fmt.Println("diskinfo not found", p)
		}
	}
	return diskUsed, nil
}

//InitSelfPicker 初始化采集自身参数模块
func InitSelfPicker(w *sync.WaitGroup) {
	w.Add(1)
	beginTask()

}

/*

1000003101 CPU核占用率
CPU总占用率	1000003001
内存占用率	1000003201
内存总数	1000003301
存储空间	1000004001
存储占用率	1000003701
存储挂载位置	1000003801
总存储空间	1000004101
总存储占用率	1000003901


*/
const cpuCoreID = "cpuCoreRates"
const cpuID = "cpuRate"
const memID = "ramRateUsed"
const memTotalID = "ram"

/*onst storeSpaceID uint64 = 1000004001
const storePointID uint64 = 1000003801
const storeUsedID uint64 = 1000003701
*/
const storeStateID = "storeInfo"
const storeTotalID = "totalSpace"
const storeTotalUsedID = "usedRate"
const cpuTemperature = "boardTemp"

//var mark = 0
var ID = config.SelfOption.ID

func SetID(id string) {
	ID = id
}

func task() {
	//mark++
	cache.SetLastAliveTime(ID, time.Now().Unix())
	mem, mt := GetMemPercent()
	//ps, used, _ := GetDiskPercent()
	now := time.Now().Unix()

	pRData := new(propertytype.Value)
	pRData.TID = ID
	pRData.ReportTime = now
	pRData.PickTime = now
	//data := realdata.DataReport{ObjID: config.Cfg.SelfID, ReportTime: now.Unix()}
	//data.PID = cpuCoreID
	//cpuCoreLen := len(cpuCoreID)
	// var ap float64
	//var mid =
	cpus := GetCPUPercent(true)
	if cpus != nil {
		pRData.PID = cpuCoreID
		pRData.Value = cpus
		//pRData.V = cpus
		notify.RawDataEx(pRData)
	}

	tcpu := GetCPUPercent(false)
	if len(tcpu) == 1 {
		pRData.Value = tcpu[0]
		pRData.PID = cpuID
		//ap = ap / float64(len(cpus))

		notify.RawDataEx(pRData)
	}

	//data.Value = strconv.FormatFloat(ap, 'f', 1, 64)
	//realdata.PSDataReady(&data, rc)

	pRData.PID = memID
	//data.Value = strconv.FormatFloat(mem, 'f', 1, 64)
	pRData.Value = mem
	notify.RawDataEx(pRData)

	pRData.PID = memTotalID
	//data.Value = strconv.FormatUint(mt, 10)
	pRData.Value = mt
	notify.RawDataEx(pRData)
	values, _ := GetDiskInfo()
	if runtime.GOOS == "windows" {
		if values != nil {
			pRData.Value = values
			pRData.PID = storeStateID
			notify.RawDataEx(pRData)
		}
	}
	//values, _ := GetDiskInfo()

	/*
		if values != nil {
			pRData.Value = values
			pRData.PID = storeStateID
			realdata.PSDataReady(pRData, rc)
		}*/

	var total float64
	var tused float64
	for _, pi := range diskUsed {

		total += pi.Total
		tused += pi.Used
	}
	pRData.PID = storeTotalID
	pRData.Value = total
	notify.RawDataEx(pRData)

	var tusedp = (tused * 100.00) / total
	pRData.PID = storeTotalUsedID
	pRData.Value = tusedp
	//data.Value = float64(tusedp)
	notify.RawDataEx(pRData)
	if runtime.GOOS == "linux" {
		temp := Cmd("echo $[$(cat /sys/class/thermal/thermal_zone0/temp)/1000]", true)

		if len(temp) > 0 {
			stemp := string(temp)
			stemp = strings.Replace(stemp, " ", "", -1)
			stemp = strings.Replace(stemp, "\n", "", -1)
			stemp = strings.Replace(stemp, "\r\n", "", -1)
			stemp = strings.Replace(stemp, "$", "", -1)
			stemp = strings.Replace(stemp, "[", "", -1)
			stemp = strings.Replace(stemp, "]", "", -1)

			if strings.Contains(stemp, "/") {
				sDiv := strings.Split(stemp, "/")
				if len(sDiv) == 2 {
					fir, err := strconv.ParseFloat(sDiv[0], 64)
					if err == nil {
						sec, err := strconv.ParseFloat(sDiv[1], 64)
						if err == nil && sec >= 999 {
							ftemp := fir / sec
							pRData.PID = cpuTemperature
							pRData.Value = ftemp
							notify.RawDataEx(pRData)
							fmt.Println("temperature", pRData)
						} else {
							fmt.Println("temperature error /--**00000****----", err)
						}

					} else {
						fmt.Println("temperature error /--******----", err)
					}
				} else {
					fmt.Println("temperature error fmt error", sDiv, len(sDiv))
				}
			} else {
				ftemp, err := strconv.ParseFloat(stemp, 64)
				if err == nil {
					pRData.PID = cpuTemperature
					pRData.Value = ftemp
					notify.RawDataEx(pRData)
					//fmt.Println("temperature", pRData)
				} else {

					fmt.Println("temperature error", err)
				}
			}

		} else {
			fmt.Println("no data ", temp)
		}
	}

}
func beginTask() {
	timer.BeginTimerThrd(60, true, true, task)

}
